const { declare } = require('@babel/helper-plugin-utils')
const importModule = require('@babel/helper-module-imports')
const fs = require('fs-extra')
const path = require('path')
const {default:generate} = require('@babel/generator')

let isStep = (path) => {
	if(path.findParent(p => p.isImportDeclaration())) return true
	if(path.node.leadingComments) {
		return path.node.leadingComments.some(item => item.value.includes('i18n-disable'))
	}
	return false
}

module.exports = declare((api, options, dirname) => {

	api.assertVersion(7)
	// 拿到babel options 要转换的语言
	let {
		locale
	} = options
	return {
		pre(file) {
			// 语言包的文件路径
			let localePath = `./${locale}.json`
			// 判断转换函数的文件是否存在
			if(!fs.pathExistsSync(process.cwd()+'/src/i18n/i18n-util.js')) {
				let transformCode = `
					import locale from '${localePath}'
					export default function transform(key,...args) {
						return locale[key].replace(/\{placeholder\}/, () => args[index++])
					}
				`
				fs.outputFileSync(process.cwd()+'/src/i18n/i18n-util.js', transformCode)
			}
			file.localeId = 0
			file.outputFile = {}
		},
		visitor: {
			Program: {
				enter(path, state) {
					path.traverse({
						ImportDeclaration(curpath) {
							let requirePath = curpath.get('source')
							let requireValue = requirePath.node.value
							if(requireValue === './i18n-util.js') {
								let importPath = curpath.get('specifiers')[0].get('local')
								let importIdentifier = importPath.node.name
								state.importIdentifier = importIdentifier
								curpath.stop()
							}
						}
					})
					if(!state.importIdentifier) {
						state.importIdentifier  = importModule.addDefault(path, './i18n-util.js',{
							nameHint: path.scope.generateUid('./i18n-util.js')
						}).name
					}
				}
			},
			StringLiteral(path, state) {
				if(isStep(path)) return
				// 能找到说明是jsx 的 attr
				let parent = path.findParent(p => p.isJSXAttribute())
				let localeId = ++state.file.localeId
				// 统计到输出json的对象中
				state.file.outputFile[`${parent?parent.node.name.name:''}${localeId}`] = path.node.value
				let replaceExpression = api.template.ast(`${state.importIdentifier}('${parent?parent.node.name.name:''}${localeId}')`).expression
				// jsx attr 的值要加{}
				if (path.findParent(p => p.isJSXAttribute()) && !path.findParent(p=> p.isJSXExpressionContainer())) {
					replaceExpression = api.types.JSXExpressionContainer(replaceExpression);
				}
				path.replaceWith(replaceExpression)
				path.skip()
			},
			TemplateLiteral(path, state) {
				if(isStep(path)) return
				// 能找到说明是jsx 的 attr
				let parent = path.findParent(p => p.isJSXAttribute())
				// ${xxx + xxx} 转为code
				let localeId = ++state.file.localeId
				state.file.outputFile[`${parent?parent.node.name.name:''}${localeId}`] = path.get('quasis').map(item => item.node.value.raw).join('{placeholder}')
				const value = path.node.expressions.map(item => generate(item).code)
				let replaceExpression = api.template.ast(`${state.importIdentifier}('${parent?parent.node.name.name:''}${localeId}',${value.join(',')})`).expression
				if (path.findParent(p => p.isJSXAttribute()) && !path.findParent(p=> p.isJSXExpressionContainer())) {
					replaceExpression = api.types.JSXExpressionContainer(replaceExpression);
				}
				path.replaceWith(replaceExpression)
				path.skip()
			}
		},
		post(file) {
			let {
				outputFile,
			} = file
			let localeZhPath = `./src/i18n/zh-CN.json`
			let localeEnPath = `./src/i18n/en-US.json`
			fs.outputFileSync(path.join(process.cwd(), localeZhPath), JSON.stringify(outputFile, null, 2))
			fs.outputFileSync(path.join(process.cwd(), localeEnPath), JSON.stringify(outputFile, null, 2))
		}
	}
})
